﻿Imports System.Windows
Imports System.ComponentModel
Imports System.Reflection

Public Class EventBinder
    Inherits DependencyObject




    Public Shared Function GetEvent(ByVal element As DependencyObject) As String
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If

        Return element.GetValue(EventProperty)
    End Function

    Public Shared Sub SetEvent(ByVal element As DependencyObject, ByVal value As String)
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If

        element.SetValue(EventProperty, value)
    End Sub

    Public Shared ReadOnly EventProperty As  _
                           DependencyProperty = DependencyProperty.RegisterAttached("Event", _
                           GetType(String), GetType(EventBinder), _
                           New FrameworkPropertyMetadata(AddressOf HandlerOrEventChanged))



    Public Shared Function GetHandler(ByVal element As DependencyObject) As String
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If

        Return element.GetValue(HandlerProperty)
    End Function

    Public Shared Sub SetHandler(ByVal element As DependencyObject, ByVal value As String)
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If

        element.SetValue(HandlerProperty, value)
    End Sub

    Public Shared ReadOnly HandlerProperty As  _
                           DependencyProperty = DependencyProperty.RegisterAttached("Handler", _
                           GetType(String), GetType(EventBinder), _
                           New FrameworkPropertyMetadata(AddressOf HandlerOrEventChanged))



    Public Shared Function GetHandlerObject(ByVal element As DependencyObject) As Object
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If

        Return element.GetValue(HandlerObjectProperty)
    End Function

    Public Shared Sub SetHandlerObject(ByVal element As DependencyObject, ByVal value As Object)
        If element Is Nothing Then
            Throw New ArgumentNullException("element")
        End If

        element.SetValue(HandlerObjectProperty, value)
    End Sub

    Public Shared ReadOnly HandlerObjectProperty As  _
                           DependencyProperty = DependencyProperty.RegisterAttached("HandlerObject", _
                           GetType(Object), GetType(EventBinder), _
                           New FrameworkPropertyMetadata(AddressOf HandlerOrEventChanged))





    Private Shared Sub HandlerOrEventChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
        If d Is Nothing Then Return

        Dim ev = GetEvent(d)
        Dim h = GetHandler(d)
        Dim ho = GetHandlerObject(d)

        If String.IsNullOrEmpty(ev) Or String.IsNullOrEmpty(h) Or ho Is Nothing Then Return

        Dim handlerinfo As MethodInfo = ho.GetType().GetMethod(h)
        Dim eventinfo As EventInfo = d.GetType().GetEvent(ev)

        If handlerinfo Is Nothing Or eventinfo Is Nothing Then Return

        eventinfo.AddEventHandler(d, [Delegate].CreateDelegate(eventinfo.EventHandlerType, ho, h))

    End Sub


End Class
